package tileStyle;

import java.util.*;
import tileStyle.Prism.*;

public class Seed implements Iterator<NodeAddress> {
	
	protected List<NodeAddress> addresses;
	protected int turn;
	protected int current;
	protected boolean building;

	public Seed() {
		addresses = new ArrayList<NodeAddress>();
		current = -1;
		turn = -1;
		building = true;
	}
	
	public void addNodeAddress(NodeAddress address) throws TileStyleException {
		if (building)
			addresses.add(address);
		else
			throw new TileStyleException("Tried to add to a Seed object after it was built.");
	}
	
	public void setTurn() throws TileStyleException {
		if (turn != -1)
			throw new TileStyleException("Tried to set turn after it was already set.");
		if (building)
			turn = addresses.size() - 1;
		else 
			throw new TileStyleException("Tried to set turn after the Seed object was built.");
	}
	
	public void setBuilt() {
		building = false;
		current = 0;
	}

	public boolean hasNext() {
		if (building)
			throw new TileStyleException("Tried to check a Seed's hasNext while it was building.");
		else 
			return addresses.size() > current;
	}
	
	public NodeAddress next() throws NoSuchElementException {
		if (building)
			throw new TileStyleException("Tried to get a Seed's next while it was building.");
		else {
			current++;
			return addresses.get(current-1);
		}
	}
	
	public NodeAddress getNeighbor(int direction) {
		int prev, next;
		int pointer = current - 1;
		if (pointer < turn) { 
			prev = TileType.WEST;
			next = TileType.EAST;
		}
		else if (current == turn) {
			prev = TileType.WEST;
			next = TileType.NORTH;
		}
		else {
			prev = TileType.SOUTH;
			next = TileType.NORTH;
		}
	
		NodeAddress answer = null;
		if ((prev == direction) && (pointer != 0)) 
			answer = addresses.get(pointer - 1);
		if ((next == direction) && (pointer != (addresses.size() - 1)))
			answer = addresses.get(current + 1);
		
		return answer;
	}
	
	public void remove() throws UnsupportedOperationException {
		throw new UnsupportedOperationException();
	}
	
}
